/**
 * Collaborative Story Development Web Application (CSDApp) Copyright Anton
 * Strack 2014
 *
 * This file is part of Collaborative Story Development Application (CSDApp).
 *
 * CSDApp is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or any later version.
 *
 * CSDApp is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * CSDApp. If not, see <http://www.gnu.org/licenses/>.
 *
 */
package csdwa;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * This class handles the user interaction wit the application. It provides a
 * map between the HttpServlet and the CsdwaController that will process the
 * request.
 *
 * @author Anton Strack
 */
public class CoreController extends HttpServlet {

    private static final long serialVersionUID = 1L;
    /**
     * The jsp page that will be displayed to the user.
     */
    private String target;
    /**
     * the datasource used by the controller and passed to the other classes.
     */
    protected Datasource ds;
    protected Connection conn;
    /**
     * The primary logic handler and entry point into the system.
     */
    private ResourceRequestDelegator ResourceRequestDelegator;
    /**
     * A database retrieved repository of ids and names for resources, actions,
     * roles, states, and task actions.
     */
    private InfoAggregator ia;
    private String basepath;

    @Override
    public void init() throws ServletException {
        super.init();
        basepath = getServletContext().getRealPath("/") + "WEB-INF";
        this.ia = InfoAggregator.getInstance();
    }

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.ds = CSDAppFactory.getDatasource(this.basepath);
        this.conn = ds.getConnection();
        this.ResourceRequestDelegator = new ResourceRequestDelegator(conn);
        // intitialize and populate the InfoAggregator here so it is always done on each request.
        ia.initialize(ds, true);
        ia.populateActionTypes();
        ia.populateResourceTypes();
        ia.populateRoleTypes();
        ia.populateStateTypes();
        ia.populateTaskActionTypes();

        String requestType = request.getParameter("rtype");
        request = this.ResourceRequestDelegator.processRequest(request, response);
        response = this.ResourceRequestDelegator.getProcessedResponse();
        HttpSession session = request.getSession();
        ServletContext context = session.getServletContext();

        String openshift_homedir = System.getenv("OPENSHIFT_HOMEDIR");
        if (openshift_homedir == null || openshift_homedir.isEmpty()) {
            request.setAttribute("config", new Configuration("/CSDAppOpenshift/index")); // TESTING LOCAL
        } else {
            request.setAttribute("config", new Configuration("/index"));//request.getRequestURI()));
        }

        // set the source so that the index.jsp page will know to redirect to the servlet if it isn't set to "controller".
        request.setAttribute("source", "controller");

        this.target = (String) request.getAttribute("requestView");

        if (this.target == null || this.target.isEmpty()) {
            this.target = "/index.jsp";// default home page on first visit if requestView fails to be set
        }

        try {
            if (conn.isClosed() == false) {
                conn.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(ResourceRequestDelegator.class.getName()).log(Level.SEVERE, null, ex);
        }

        if (requestType != null && requestType.equalsIgnoreCase(RequestType.ASYNC.toString())) {
            response.setContentType("text/html");
            response.getWriter().write(request.getAttribute("requestResultMessageType").toString());
        } else {
            try {
                RequestDispatcher dispatcher = context.getRequestDispatcher(this.target);
                dispatcher.forward(request, response);
            } catch (ServletException ex) {
                Logger.getLogger(ResourceRequestDelegator.class.getName()).log(Level.SEVERE, "RequestDispatcher ServletException:" + ex.getMessage(), ex);
            } catch (IOException ex) {
                Logger.getLogger(ResourceRequestDelegator.class.getName()).log(Level.SEVERE, "RequestDispatcher IOException:" + ex.getMessage(), ex);
            }
        }
    }

    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            this.processRequest(request, response);
        } catch (Exception ex) {
            System.err.println("Exception caught in CoreController doGet()." + ex.getMessage());
            ex.printStackTrace();
        } finally {
        }
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            // forward the request for common setup and dispatch.
            this.processRequest(request, response);
        } catch (Exception ex) {
            System.err.println("Exception caught in CoreController doPost()." + ex.getMessage());
            ex.printStackTrace();
        } finally {
        }
    }
}
